/** 
 * @(#)MessagePush.java 1.0.0 2015年3月27日 下午3:16:54  
 *  
 * Copyright © 2015 善林金融.  All rights reserved.  
 */

package com.niuwa.p2p.service.impl.message;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.jpush.api.JPushClient;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.niuwa.p2p.core.utils.AppConstants;

/**
 * 消息推送 采用第三方jpush极光推送 参考文档 http://docs.jpush.cn/display/dev/Index
 * 
 * @author zhangmingtao
 * @version $Revision:1.0.0, $Date: 2015年3月27日 下午3:16:54 $
 */
public class MessagePush {

	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private static final String masterSecret = "bf6541de9b80b2c9497e7f72";
	private static final String appKey = "26f0617b7eaeaf842f5671e5";

	/* 这是在极光网站上申请的密钥 */
	// private static final String masterSecret = "bf6541de9b80b2c9497e7f72";
	/* 应用的appKey,同样在网站上申请 */
	// private static final String appKey = "26f0617b7eaeaf842f5671e5";
	/* maxRetryTime:最大的尝试次数，设为3表示：跟服务器进行建立连接若失败会尝试再进行两次尝试 */
	private static final int maxRetryTime = 3;
	/* 建立JpushClient类，用来发送消息的对象 */
	private JPushClient jPushClient = null;

	public String title;

	public String message;

	public String nwMsgType;

	public String memo;

	/**
	 * 消息构建（无备注信息）
	 * 
	 * @param title
	 * @param message
	 * @param nwMessageType
	 */
	public MessagePush(String title, String message, String nwMsgType) {
		this.message = message;
		this.title = title;
		this.nwMsgType = nwMsgType;
		this.memo = "";
		jPushClient = new JPushClient(masterSecret, appKey, maxRetryTime);
	}

	/**
	 * 消息构建（有备注信息）
	 * 
	 * @param title
	 * @param message
	 * @param nwMessageType
	 */
	public MessagePush(String title, String message, String nwMsgType, String memo) {
		this.message = message;
		this.title = title;
		this.nwMsgType = nwMsgType;
		this.memo = memo == null ? "" : memo;
		jPushClient = new JPushClient(masterSecret, appKey, maxRetryTime);
	}

	/**
	 * 向指定别名的客户端[发送消息]
	 * 
	 * @param set
	 * @return
	 */
	public void sendPushAliasMessage(Set<String> set) {
		PushPayload pushPayload = buildObject_audience_alias_message(set);
		System.err.println("发送自定义消息：" + pushPayload.toString());
		PushResult pushResult = null;
		try {
			pushResult = jPushClient.sendPush(pushPayload);
			logger.info("返回自定义消息ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
			System.out.println("返回自定义消息ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
		} catch (APIConnectionException e) {
			logger.error(this.getClass().getSimpleName() + " jpush发送消息错误: " + e.getMessage());
		} catch (APIRequestException e) {
			logger.error(this.getClass().getSimpleName() + " jpush发送消息错误: " + e.getMessage());
		}
	}

	/**
	 * 向指定别名的客户端[发送通知]
	 * 
	 * @param alias
	 * @return
	 * 
	 */
	public void sendPushAliasNotification(Set<String> alias) {
		PushPayload pushPayload = buildObject_audience_alias_notification(alias);
		System.err.println("发送通知：" + pushPayload.toString());
		try {
			PushResult pushResult = jPushClient.sendPush(pushPayload);
			logger.info("返回通知ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
			System.out.println("返回通知ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
		} catch (APIConnectionException e) {
			e.printStackTrace();
			logger.error(this.getClass().getSimpleName() + " jpush发送通知错误: " + e.getMessage());
		} catch (APIRequestException e) {
			logger.error(this.getClass().getSimpleName() + " jpush发送通知错误: " + e.getMessage());
		}
	}

	/**
	 * 发送广播
	 */
	public void sendPushAll() {
		PushPayload pushPayload = buildPushObject_all_all_alert();
		System.err.println("发送广播：" + pushPayload.toString());
		try {
			PushResult pushResult = jPushClient.sendPush(pushPayload);
			logger.info("返回广播ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
			System.out.println("返回广播ID:" + pushResult.msg_id + " 状态码：" + pushResult.isResultOK());
		} catch (APIConnectionException e) {
			logger.error(this.getClass().getSimpleName() + " jpush发送广播错误: " + e.getMessage());
		} catch (APIRequestException e) {
			logger.error(this.getClass().getSimpleName() + " jpush发送广播错误: " + e.getMessage());
		}
	}

	/**
	 * 封装【发送消息】到指定别名的设备 alias:用别名来标识一个用户。一个设备只能绑定一个别名，但多个设备可以绑定同一个别名。 一次推送最多1000
	 * 个; tags: 用标签来进行大规模的设备属性、用户属性分群。一次推送最多 20 个 tag
	 * 
	 * @param alias
	 * @return
	 */
	public PushPayload buildObject_audience_alias_message(Set<String> alias) {
		return PushPayload.newBuilder().setPlatform(Platform.android_ios()).setAudience(Audience.alias(alias)).setMessage(init_buildObject_audience_alias_message()).build();
	}

	private Message init_buildObject_audience_alias_message() {
		return Message.newBuilder().setMsgContent(message).setTitle(title).addExtras(addExtraMap()).build();
	}

	/**
	 * 发送通知
	 * 
	 * @param alias
	 *            别名
	 * @return
	 */
	public PushPayload buildObject_audience_alias_notification(Set<String> alias) {
		return PushPayload.newBuilder().setPlatform(Platform.android_ios()).setAudience(Audience.alias(alias)).setNotification(init_buildObject_audience_alias_notification()).build();
	}

	private Notification init_buildObject_audience_alias_notification() {
		return Notification.newBuilder().addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).setAlert(message).addExtras(addExtraMap()).build()).addPlatformNotification(IosNotification.newBuilder().setAlert(message).addExtras(addExtraMap()).incrBadge(1).build()).build();
	}

	/**
	 * 自定义参数
	 * 
	 * @return
	 */
	private Map<String, String> addExtraMap() {
		return Maps.newHashMap(ImmutableMap.of("nwMessageType", nwMsgType, "title", title, "memo", memo, "nwMessageClassify", Lists.newArrayList(AppConstants.APP_PUSH_MESSAGE).contains(nwMsgType) ? "1" : (Lists.newArrayList(AppConstants.APP_PUSH_NOTIFICATION).contains(nwMsgType) ? "2" : "")));
	}

	/**
	 * 广播推送
	 * 
	 * @return
	 */
	public PushPayload buildPushObject_all_all_alert() {
		return PushPayload.alertAll(message);
	}

	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("1001");
		MessagePush messagePush = new MessagePush("别名927一条测试信息ID:020facfbc16", "标题是什么", "1");
		messagePush.sendPushAliasMessage(set);
	}

}
